<?php

namespace App\Http\Services;

use App\Http\Repositories\Daos\Order\GoodsOrderDao;
use App\Http\Repositories\Redis\UserRedis;
use App\Http\Requests\UserContext;
use App\Http\Traits\Errors;
use App\Http\Traits\GlobalConstant;
use App\Models\Goods;
use App\Models\GoodsOrder;
use App\Models\Message;
use App\Models\Shop;
use App\Models\Users;
use App\Util\Helper;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class GoodsOrderService extends BaseService
{
    use Errors;

    protected $goodsOrderDao;

    public function __construct(GoodsOrderDao $goodsOrderDao)
    {
        $this->goodsOrderDao = $goodsOrderDao;
    }

    public function lists(UserContext $userContext)
    {
        $userId    = $userContext->getId();
        $state     = request('state') ?? 0;
        $condition = [
            'user_id' => $userId,
        ];
        $page      = request('page') ?? 1;
        $size      = request('size') ?? 10;
        $field     = ['*'];
        $offset    = ($page * $size) - $size;
        $query     = $this->goodsOrderDao->getModel()->with(["shopInfo" => function ($query) {
            $query->select(['id', 'name']);
        }])->where($condition);

        if (!empty($state)) {
            $query = $query->where('status', $state);
        }
        $list = $query->orderBy('status', 'asc')->limit($size)->offset($offset)->get($field);
        if (!empty($list)) {
            foreach ($list as &$item) {
                $item['xd_date']    = substr($item['created_at'], 0, 16);
                $item['status_tip'] = GlobalConstant::setStatusTip($item['status']);
            }
            unset($item);
        }
        return $list;
    }

    public function createGoodsOrder(UserContext $userContext)
    {
        $userId  = $userContext->getId();
        $goodsId = request('goods_id') ?? 0;
        if (empty($goodsId)) $this->showError('请选择商品');
        $goodsInfo = Goods::where('id', $goodsId)->first();
        if (!$goodsInfo) $this->showError('商品不存在');
//        $goodsOrderInfo = $this->goodsOrderDao->getModel()->where('user_id', $userId)->where('goods_id', $goodsId)->first();
//        if (!empty($goodsOrderInfo)) $this->showError('你已经兑换过该商品');
        $orderSn   = Helper::sn(20, 2);
        $code      = Helper::randString(12, 1);
        $orderData = [
            'order_sn'    => $orderSn,
            'verify_code' => $code,
            'user_id'     => $userId,
            'goods_id'    => $goodsId,
            'shop_id'     => $goodsInfo['shop_id'],
            'goods_score' => $goodsInfo['score'],
            'qty'         => 1,
            'status'      => 1,
            'goods_snap'  => ['title' => $goodsInfo['title'], 'discover' => $goodsInfo['pics'][0], 'score' => $goodsInfo['score']]
        ];
        DB::beginTransaction();
        try {
            //库存操作
            $result = Goods::where('id', $goodsId)->where('qty', '>=', 1)->decrement('qty', 1);
            if (!$result) {
                $this->showError('store_invalid');
            }
            //积分减少
            $rel = Users::where('id', $userId)->where('score', '>=', $goodsInfo['score'])->decrement('score', $goodsInfo['score']);
            if (!$rel) {
                $this->showError('积分不足');
            }

            //创建订单
            $order = $this->goodsOrderDao->save($orderData);
            DB::commit();
        } catch (\Exception $exception) {
            DB::rollBack();
            Log::error('兑换商品失败:' . $exception->getMessage() . '行' . $exception->getLine() . '文件' . $exception->getFile());
            $this->showError($exception->getMessage());
        }
        UserRedis::getRedisInstance()->updateNode($userId);
        return [
            'order_sn' => $orderSn,
            'id'       => $order['id'],
        ];
    }

    public function orderDetail(UserContext $userContext)
    {
        $userId  = $userContext->getId();
        $role    = request('role') ?? 0;
        $orderId = request('o_id') ?? '';
        $query   = $this->goodsOrderDao->getModel()->where('id', $orderId);
        if (empty($role) || $role != 3) {
            $query->where('user_id', $userId);
        }
        $detail = $query->with(["shopInfo"])->first();
        if ($detail) {
            $detail->status_tip = GlobalConstant::setStatusTip($detail->status);
            $detail->xd_date    = substr($detail->created_at, 0, 10);
//            $detail->qrhttp     = config('app.url') . '?oid=' . $orderId;
//            $detail->qrhttp = config('app.url') . '/' . $orderId;
            $detail->qrhttp = $detail->verify_code;
            if (!empty($detail->use_at)) $detail->use_at = date('Y-m-d H:i:s', $detail->use_at);
        }
        return $detail;
    }

    public function orderGoodStatics(UserContext $userContext)
    {
        $userId = $userContext->getId();
        return $this->goodsOrderDao->getModel()->where('user_id', $userId)->select('status')->selectRaw('count(*) as total,status')->groupBy('status')->get();
    }

    public function goodsLists()
    {
        $shopId = request('shop_id') ?? 0;
        $status = request('state') ?? 1;
        $page   = request('page') ?? 1;
        $size   = request('size') ?? 10;
        $field  = ['id', 'shop_id', 'title', 'score', 'qty', 'pics', 'status'];
        $offset = ($page * $size) - $size;
        $list   = Goods::where('shop_id', $shopId)->where('status', $status)->orderBy('status', 'asc')->limit($size)->offset($offset)->get($field);
        if (!empty($list)) {
            foreach ($list as &$item) {
                $item['order_count'] = $this->goodsOrderDao->getModel()->where('goods_id', $item['id'])->count();
            }
            unset($item);
        }
        return $list;
    }

    public function goodsStatics()
    {
        $shopId = request('shop_id') ?? 0;
        return Goods::where('shop_id', $shopId)->groupBy('status')->selectRaw('count(*) as total,status')->get();
    }

    public function goodsUpdate(UserContext $userContext)
    {
        $shopId  = request('shop_id') ?? 0;
        $goodsId = request('goods_id') ?? 0;
        $status  = request('state') ?? -1;
        $userId  = $userContext->getId();
        if (!isset($status) || $status == -1) $this->showError('上下商品失败');
        if (empty($shopId)) $this->showError('店铺异常');
        if (empty($goodsId)) $this->showError('商品异常');
        $shopInfo = Shop::where('id', $shopId)->where('user_id', $userId)->where('status', 1)->first();
        if (empty($shopInfo)) $this->showError('店铺信息异常或关闭');
        $goodsInfo = Goods::where('shop_id', $shopId)->where('id', $goodsId)->first();
        if (empty($goodsInfo)) $this->showError('商品信息异常');
        $goodsInfo->status = $status;
        $goodsInfo->save();
        return true;
    }

    public function shopStatic(UserContext $userContext)
    {
        $userId = $userContext->getId();
        return $this->goodsOrderDao->getModel()->whereIn('shop_id', function ($q) use ($userId) {
            $q->select('id')->where('user_id', $userId)->from('shop');
        })->selectRaw('IFNULL(SUM(goods_score), 0) AS total_score,count(*) as total_order')->first();
    }

    public function allShopGoods(UserContext $userContext)
    {
//        $userId = 122413;
        $userId = $userContext->getId();
        $page   = request('page') ?? 1;
        $size   = request('size') ?? 10;
        $field  = ['id', 'name'];
        $offset = ($page * $size) - $size;
        return Shop::whereIn('id', function ($q) use ($userId) {
            $q->select('id')->where('user_id', $userId)->from('shop');
        })->with(["goods" => function ($q) {
            $q->select(['shop_id', 'pics']);
        }])->withCount(["goods", "orders"])->limit($size)->offset($offset)->get($field);
    }

    public function shopOrder()
    {
        $shopId    = request('shop_id') ?? 0;
        $state     = request('state') ?? -1;
        $keyword   = request('keyword') ?? '';
        $condition = [
            'shop_id' => $shopId,
        ];
        if ($state != -1) {
            $condition['status'] = $state;
        }
        $page   = request('page') ?? 1;
        $size   = request('size') ?? 10;
        $field  = ['id', 'user_id', 'goods_snap', 'created_at as publish', 'goods_score', 'status'];
        $offset = ($page * $size) - $size;
        $query  = $this->goodsOrderDao->getModel()->where($condition)
            ->with(["userInfo" => function ($q) {
                $q->select(['id', 'nickname', 'avatar']);
            }]);
        if (!empty($keyword)) {
            $query->whereRaw("(json_unquote( json_extract( `goods_snap`, '$.\"title\"' ) ) like '%$keyword%' or user_id in (select id from users where mobile like '%$keyword%'))");
        }
        $list = $query->orderBy('created_at', 'desc')->limit($size)->offset($offset)->get($field);
        if (!empty($list)) {
            foreach ($list as &$item) {
                $item['status_tip'] = GlobalConstant::setStatusTip($item['status']);
            }
            unset($item);
        }
        return $list;
    }

    public function shopOrderStatics()
    {
        $shopId  = request('shop_id') ?? 0;
        $keyword = request('keyword') ?? '';
        $query   = $this->goodsOrderDao->getModel()->where('shop_id', $shopId);
        if (!empty($keyword)) {
            $query->whereRaw("(json_unquote( json_extract( `goods_snap`, '$.\"title\"' ) ) like '%$keyword%' or user_id in (select id from users where mobile like '%$keyword%'))");
        }
        return $query->groupBy('status')->selectRaw('count(*) as total,status')->get();
    }

    public function verifyOrder(UserContext $userContext)
    {
        $userId = $userContext->getId();
        $code   = request('code') ?? '';
        Log::info('券码' . $code);
        $info = GoodsOrder::where('verify_code', $code)->first();
        empty($info) && $this->showError('券码不存在');
        $shopArray = Shop::where('user_id', $userId)->get(['id'])->toArray();
        empty($shopArray) && $this->showError('当前用户不存在店铺');
        $shopIds = array_column($shopArray, 'id');
        if (!in_array($info['shop_id'], $shopIds)) $this->showError('当前券码不在当前用户所在店铺');
        if ($info['use_at'] != 0 || $info['status'] != 1) $this->showError('券码已使用');
        DB::beginTransaction();
        try {
            $info->status = 2;
            $info->use_at = time();
            $info->save();
            //给店铺对应的用户增加积分
            $shopUserId = Shop::where('id', $info['shop_id'])->value('user_id');
            Message::create(['user_id' => $shopUserId, 'title' => '积分变动提醒', 'content' => '订单' . $info['order_sn'] . '核销完成获得' . $info['goods_score'] . '积分']);
            Users::where('id', $shopUserId)->increment('score', $info['goods_score']);
            DB::commit();
        } catch (\Exception $exception) {
            DB::rollBack();
            $this->showError($exception->getMessage());
        }
        UserRedis::getRedisInstance()->updateNode($shopUserId);
        return true;
    }

}
